package com.fingard.dsp.bank.directbank.zyb02;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 *
 * @author wuch
 * @version 创建时间：2017年10月25日 下午2:32:53
 */
public class SecureIdentityUtil {

    // dev
    private static byte[] BLOWFISH_KEY_DEV;
    // online
    private static byte[] BLOWFISH_KEY_ONLINE;

    static {
        try {
            BLOWFISH_KEY_DEV = "atscloud dev key".getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            BLOWFISH_KEY_DEV = "atscloud dev key".getBytes();
        }
        try {
            BLOWFISH_KEY_ONLINE = "2390jfjaoifasdnn3jkb32baposf903ui23j".getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            BLOWFISH_KEY_ONLINE = "2390jfjaoifasdnn3jkb32baposf903ui23j".getBytes();
        }
    }


    static final String initEncode(byte[] kbytes, String secret) throws NoSuchAlgorithmException,
            NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,UnsupportedEncodingException {
        SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
        Cipher cipher = Cipher.getInstance("Blowfish");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encoding = cipher.doFinal(secret.getBytes("UTF-8"));
        BigInteger n = new BigInteger(encoding);
        return n.toString(16);
    }

    public static String encode(String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException,UnsupportedEncodingException {
        return SecureIdentityUtil.encode(null, secret);
    }

    public static String encode(String encKey, String secret) throws InvalidKeyException, NoSuchAlgorithmException,
            NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,UnsupportedEncodingException {
        byte[] kbytes = SecureIdentityUtil.BLOWFISH_KEY_ONLINE;
        try {
            if (isNotBlank(encKey)) {
                kbytes = encKey.getBytes("UTF-8");
            }
            return initEncode(kbytes, secret);
        } catch (InvalidKeyException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        } catch (NoSuchAlgorithmException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        } catch (NoSuchPaddingException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        } catch (IllegalBlockSizeException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        } catch (BadPaddingException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        }catch (UnsupportedEncodingException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        }

        return initEncode(kbytes, secret);
    }

    static final String iniDecode(byte[] kbytes, String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
        BigInteger n = new BigInteger(secret, 16);
        byte[] encoding = n.toByteArray();
        // SECURITY-344: fix leading zeros
        if (encoding.length % 8 != 0) {
            int length = encoding.length;
            int newLength = ((length / 8) + 1) * 8;
            int pad = newLength - length; // number of leading zeros
            byte[] old = encoding;
            encoding = new byte[newLength];
            for (int i = old.length - 1; i >= 0; i--) {
                encoding[i + pad] = old[i];
            }
        }
        Cipher cipher = Cipher.getInstance("Blowfish");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decode = cipher.doFinal(encoding);
        return new String(decode);
    }

    public static char[] decode(String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        return SecureIdentityUtil.decode(null, secret).toCharArray();
    }

    public static String decode(String encKey, String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

        byte[] kbytes = SecureIdentityUtil.BLOWFISH_KEY_ONLINE;


        try {
            if (isNotBlank(encKey)) {
                kbytes = encKey.getBytes("UTF-8");
            }
            return iniDecode(kbytes, secret);
        } catch (InvalidKeyException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        } catch (BadPaddingException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        } catch (IllegalBlockSizeException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        }catch (UnsupportedEncodingException e) {
            kbytes = SecureIdentityUtil.BLOWFISH_KEY_DEV;
        }
        return iniDecode(kbytes, secret);
    }

    static final boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    static final boolean isBlank(String str) {
        int strLen = 0;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException,
            BadPaddingException, IllegalBlockSizeException,UnsupportedEncodingException {
        System.out.println("acccore: "+new String(SecureIdentityUtil.encode("acccore")));
        System.out.println("acccore: "+new String(SecureIdentityUtil.decode("-3d978018aa4a07c7")));
    }

}
